package org.jeeasy.common.core.base.convert;

import org.jeeasy.common.core.annotation.convert.BeanTransfer;
import org.mapstruct.factory.Mappers;

/**
 * 定义一个基础数据对象接口，用于实体类到传输对象的转换
 * 此接口主要目的是通过MapStruct库实现实体类与传输对象之间的自动转换
 * 它使用了MapStruct的映射器来完成转换逻辑
 *
 * @param <DO> 泛型参数，表示继承自BaseDO的实体类
 */
public interface BaseDO<DO extends BaseDO<DO>> {

    /**
     * 根据传输对象的类获取对应的映射器
     * 此方法是私有的，用于内部获取映射器实例
     * 它通过反射获取类上的BeanTransfer注解来确定使用哪个映射器
     *
     * @param clazz      传输对象的类，用于获取映射器
     * @param <TRANSFER> 泛型参数，表示继承自BaseTransfer的传输对象
     * @return 返回一个BaseConverter实例，用于实体类和传输对象之间的转换
     */
    private <TRANSFER extends BaseTransfer<DO>> BaseConverter<DO, TRANSFER> getMapper(Class<TRANSFER> clazz) {
        // 通过反射获取类上的BeanTransfer注解
        BeanTransfer annotation = clazz.getAnnotation(BeanTransfer.class);
        // 使用MapStruct的工厂方法获取映射器实例
        return Mappers.getMapper(annotation.value());
    }

    /**
     * 将当前实体对象转换为指定类型的传输对象
     * 此方法利用MapStruct映射器将实体对象转换为传输对象
     * 它首先调用私有的getMapper方法获取映射器，然后使用该映射器进行转换
     *
     * @param clazz      指定的传输对象类型，告诉方法需要转换成的目标类型
     * @param <TRANSFER> 泛型参数，表示继承自BaseTransfer的传输对象
     * @return 返回转换后的传输对象实例
     */
    default <TRANSFER extends BaseTransfer<DO>> TRANSFER transfer(Class<TRANSFER> clazz) {
        // 调用映射器的transfer方法将当前实体对象转换为传输对象
        return getMapper(clazz).transfer((DO) this);
    }
}
